import re
import define
from data.chunk import Chunk

reg_total_time = re.compile(r'Total time:(.*?)s')
reg_file_path = re.compile(r'File:(.*)')
reg_location = re.compile(r'Function:(.*)')
reg_line_with_time = re.compile(r'\s+(\d+)\s+(\d+)\s+(\d+.\d+)\s+(\d+.\d+)\s+(\d+.\d+)\s+(.*)')
reg_line_without_time = re.compile(r'\s+(\d+)(\s{15,100})(.*)')

def as_num(x):
    y = '{:.1f}'.format(x)  # .1f 保留1位小数  想为十位就这样写10f
    return y



def analysis_file(file_path):
    """分析文件"""
    with open(file_path, 'r', encoding='utf-8') as f :
        lines = f.readlines()
    flag = 0
    temp_obj = Chunk()
    skip = 0
    chunk_list = []
    max_function_consuming_time = 0
    sentence_max_consuming_time = 0
    sentence_max_time = 0


    unit_conversion_flag = False
    unit_conversion = 0
    for index, line in enumerate(lines):
        if skip > 0:
            skip -= 1
            continue
        if flag == 0:
            match_0 = reg_total_time.match(line)
            if match_0:
                function_consuming_time = float(match_0.group(1))
                if max_function_consuming_time < function_consuming_time:
                    max_function_consuming_time = function_consuming_time
                temp_obj.set_total_time(match_0.group(1))
                flag = 1
        elif flag == 1:
            match_1 = reg_file_path.match(line)
            if match_1:
                temp_obj.set_file_path(match_1.group(1))
                flag = 2
            else:
                flag = 0
        elif flag == 2:
            match_2 = reg_location.match(line)
            if match_2:
                temp_obj.set_location(match_2.group(1))
                flag = 3
                skip = 3
            else:
                flag = 0
        elif flag == 3:
            match_line_with_time = reg_line_with_time.match(line)
            if match_line_with_time:
                line_num = int(match_line_with_time.group(1))
                hits = float(match_line_with_time.group(2))
                total_time = float(match_line_with_time.group(3))
                per_hit = float(match_line_with_time.group(4))
                per_time = float(match_line_with_time.group(5))
                sentence = match_line_with_time.group(6)
                line = [line_num, hits, total_time, per_hit, per_time, sentence]
                temp_obj.add_detail_line(line)

                if temp_obj.sentence_max_consuming_time < total_time:
                    temp_obj.set_sentence_max_consuming_time(total_time)
                if temp_obj.sentence_max_time < hits:
                    temp_obj.set_sentence_max_time(hits)
            else:
                match_line_without_time = reg_line_without_time.match(line)
                if match_line_without_time:
                    line_num = match_line_without_time.group(1)
                    sentence = match_line_without_time.group(3)
                    line = [line_num, 0,0,0,0, sentence]
                    temp_obj.add_detail_line(line)
                else:
                    # 单位换算
                    if not unit_conversion_flag:
                        unit_conversion_flag = True
                        sum_temp = 0
                        for line in temp_obj.detail_lines:
                            sum_temp += line[2]
                        unit_conversion = int(sum_temp / temp_obj.total_time)
                        unit_conversion = unit_conversion ** -1

                    for index, line in enumerate(temp_obj.detail_lines):
                        temp_obj.detail_lines[index][1] = round(temp_obj.detail_lines[index][1], 3)
                        temp_obj.detail_lines[index][2] = round(temp_obj.detail_lines[index][2] * unit_conversion,3)
                        temp_obj.detail_lines[index][3] = round(temp_obj.detail_lines[index][3] * unit_conversion,3)
                        temp_obj.detail_lines[index][4] = round(temp_obj.detail_lines[index][4], 3)
                    # 更新最高值
                    if sentence_max_consuming_time < temp_obj.sentence_max_consuming_time:
                        sentence_max_consuming_time = temp_obj.sentence_max_consuming_time
                    if sentence_max_time < temp_obj.sentence_max_time:
                        sentence_max_time = temp_obj.sentence_max_time
                    chunk_list.append(temp_obj.copy())
                    temp_obj = Chunk()
                    flag = 0
    sentence_max_consuming_time = round(sentence_max_consuming_time * unit_conversion, 3)
    return {
        define.CHUNK_LIST: chunk_list,
        define.MAX_FUNCTION_CONSUMING_TIME: max_function_consuming_time,
        define.SENTENCE_MAX_CONSUMING_TIME: sentence_max_consuming_time,
        define.SENTENCE_MAX_TIME: sentence_max_time,
    }

def select_and_sort(chunk_list, options):
    select_options = options[define.SELECTION]
    sort_type_option = options[define.SORT_TYPE]
    word_option = select_options[define.WORD]
    show_number_option = select_options[define.SHOW_NUMBER]
    function_consuming_time_option = select_options[define.FUNCTION_CONSUMING_TIME]
    sentence_max_consuming_time_option = select_options[define.SENTENCE_MAX_CONSUMING_TIME]
    sentence_max_time_option = select_options[define.SENTENCE_MAX_TIME]

    # 筛选
    select_list = []
    for chunk in chunk_list:
        # 筛选函数函数耗时
        if function_consuming_time_option and not(function_consuming_time_option[0] == 0 and function_consuming_time_option[1] == 0):
            if chunk.total_time < function_consuming_time_option[0] or chunk.total_time > function_consuming_time_option[1]:
                continue

        # 筛选句子最长耗时
        if sentence_max_consuming_time_option and not(sentence_max_consuming_time_option[0] == 0 and  sentence_max_consuming_time_option[1] == 0):
            if chunk.sentence_max_consuming_time < sentence_max_consuming_time_option[0] or chunk.sentence_max_consuming_time > sentence_max_consuming_time_option[1]:
                continue

        # 是否筛选句子最大次数
        if sentence_max_time_option and not(sentence_max_time_option[0] == 0 and  sentence_max_time_option[1] == 0):
            if chunk.sentence_max_time < sentence_max_time_option[0] or chunk.sentence_max_time > sentence_max_time_option[1]:
                continue

        select_list.append(chunk)
    select_list2 = []
    # 第2轮再来筛选文字
    if word_option:
        for chunk in select_list:
            for line in chunk.detail_lines:
                if word_option in line[5]:
                    select_list2.append(chunk)

    else:
        select_list2 = select_list
    res = []
    if sort_type_option == define.SORT_FUNCTION_CONSUMING_TIME:
        res = sorted(select_list2, key=lambda chunk: chunk.total_time, reverse=True)
    elif sort_type_option == define.SORT_SENTENCE_MAX_CONSUMING_TIME:
        res = sorted(select_list2, key=lambda chunk: chunk.sentence_max_consuming_time, reverse=True)
    elif sort_type_option == define.SORT_SENTENCE_MAX_TIME:
        res = sorted(select_list2, key=lambda chunk: chunk.sentence_max_time, reverse=True)
    
    return res[: show_number_option]
